var formBuilder = (function () {

    var config;

    var forms = [];

    var builder = function (_c) {
        config = _c;
        for (var group in config.api) {
            $('#mlist').append('<li class="list_title"><span style="font-size: 20px;font-weight: bold;color:#00beff">' + group + '</span></li>')
            for (var x in config.api[group]) {
                var input = parseFields(config.api[group][x].input);

                var form = createForm(input, config.api[group][x].apiName);
                var divTitle = config.api[group][x].title ? $("<div>").html(config.api[group][x].title) : '';
                var divDesc = config.api[group][x].desc ? $("<div style='font-size: 14px'>").html('PS:' + config.api[group][x].desc).css('padding', '10px') : '';
                var divInput = createInput(input);
                var divOutput = createOutput(config.api[group][x].output);
                var li = $("<li>").attr('id', config.api[group][x].apiName);
                var h4 = $("<h4>").text(location.protocol + '//' + location.hostname + '/api/' + config.api[group][x].apiName);
                var formBox = $("<div>");
                var formTitle = $("<h4>在线调试</h4>");

                forms.push(form);
                $('#codes').append(li.append(divTitle, h4, divDesc, divInput, divOutput, formBox.append(formTitle, form)));
                bindEvents(form);
                loadFormVars.apply(form);
                $('#mlist').append('<li><a href="#' + config.api[group][x].apiName + '">' + config.api[group][x].title.replace(/\-.*/, '') + '</a></li>');
            }
        }

        // 状态码
        var li = $("<li>").attr('id', '_code_');
        var h3 = $("<h3>").text('状态码');
        var code = $("<table class='pure-table pure-table-horizontal' style='margin-top:10px;'>");
        for (var x in config.code) {
            code.append($('<tr><td>' + config.code[x][0] + '</td><td>' + (config.code[x][1] || '操作成功') + '</td></tr>'));
        }
        $('#codes').append(li.append(h3, code));
        $('#mlist').append('<li class="list_title"><span style="font-size: 20px;font-weight: bold;color:#00beff">系统</span></li>')
        $('#mlist').append('<li><a href="#_code_"> 状态码 </a></li>');
    };

    // 解析输入参数
    var parseFields = function (apiConfig) {
        fields = [];
        for (var x in apiConfig) {
            fields.push(parseField(x, apiConfig[x]));
        }
        return fields;
    };

    var parseField = function (x, fieldConfig) {
        var c = $.trim(fieldConfig).split(';');
        var field = {
            'label': x,
            'required': false,
            'name': x,
            'type': x=='kcs_uploader_file' ? 'file' : 'text',
            'comment': ''
        };
        for (var i = 0; i < c.length; i++) {
            var _c = c[i].split('=');
            if (_c[0] == 'required') {
                field['required'] = true;
            }
            if (_c[0] == 'label') {
                field['label'] = _c[1];
            }
            if (_c[0] == 'comment' && _c[1]) {
                field['comment'] = _c[1];
            }
            if (_c[0] == 'type' && _c[1]) {
                field['type'] = _c[1];
            }
        }
        return field;
    }

    var createForm = function (fields, action) {
        var form = $('<form method="POST" target="_blank" class="pure-form pure-form-aligned" data-action="' + action + '">');

        var _g, _l, _e;
        for (var i = 0; i < fields.length; i++) {
            _g = $('<div class="pure-control-group"/>');
            _e = $('<input />').attr(fields[i]).attr('type', fields[i].type || 'text');
            ;
            _l = $('<label />').text(fields[i]['name']).addClass(fields[i]['required'] ? 'required' : '');
            _t = $('<span class="tip" style="font-size:12px;"/>').text(fields[i]['label']);
            _g.append(_l, _e, _t);
            form.append(_g);
        }
        var button = $('<div class="pure-controls"><button class="pure-button pure-button-primary" type="submit">提交</button></div>');
        form.append(button);
        return form;
    };

    var bindEvents = function (form) {
        form.find('button').click(function () {
            saveFormVars.apply(form);
        });
        form.submit(function () {
            var url = $(this).parents('li:first').find('h4:first').text();
            saveFormVars.apply(form);
            $.ajax({
                'url': url,
                'type': 'post',
                'data': new FormData(form[0]),
                'dataType': 'json',
                'processData': false,
                'contentType': false,
                'headers': {'API-TOKEN': $('#api_token').val()},
                'success': function (res) {
                    $('#output').text(JSON.stringify(res, null, "\t"));
                },
                'error': function (XMLHttpRequest, textStatus, errorThrown) {
                    $('#output').text('error : ' + textStatus + errorThrown);
                }
            });
            return false;
        });
    };

    // 输入参数列表
    var createInput = function (inputConfig) {
        var div = $("<div>");
        var h4 = $("<h4>输入参数</h4>");
        if (inputConfig.length) {
            var table = $('<table>').addClass('pure-table pure-table-bordered');
            var th, tb, tr, field;
            th = $("<thead>");
            tr = $("<tr>");
            tr.append($("<th>名称</th>"));
            tr.append($("<th>说明</th>"));
            tr.append($("<th>是否必填</th>"));
            tr.append($("<th>备注</th>"));
            table.append(th.append(tr));

            tb = $("<tbody>");
            for (var i = 0; i < inputConfig.length; i++) {
                field = inputConfig[i];
                tr = $("<tr>");
                tr.append($("<td>" + field.name + "</td>"));
                tr.append($("<td>" + field.label + "</td>"));
                tr.append($("<td>" + (field.required ? "Y" : "N") + "</td>"));
                tr.append($("<td>" + field.comment + "</td>"));
                tb.append(tr);
            }
            table.append(tb);
        }
        return div.append(h4, table);
    };

    // 输出参数列表
    var createOutput = function (outputConfig) {
        var div = $("<div>");
        var h4 = $("<h4>响应参数</h4>");
        var c = false;
        var table = $('<table>').addClass('pure-table pure-table-bordered');
        var th, tb, tr, td, field;
        tb = $("<tbody>");


        // 清理索引层级
        var clear = function (o) {
            for (var x in o) {
                if (!o.hasOwnProperty(x)) {
                    continue;
                }
                if (typeof o[x] !== 'object') {
                    continue;
                }
                if (o[x] === null || o[x] === undefined) {
                    continue;
                }
                if (x == 0) {
                    o = clear(o[x]);
                } else {
                    o[x] = clear(o[x]);
                }
            }
            return o;
        }
        outputConfig = clear(outputConfig);

        // 计算对象最大深度
        var depth = function (o) {
            var d = 0;
            var l = 0;
            var dp = [0, 0];
            for (var x in o) {
                if (!o.hasOwnProperty(x)) {
                    continue;
                }
                if (typeof o[x] !== 'object') {
                    l++;
                    continue;
                }
                if (o[x] === null || o[x] === undefined) {
                    continue;
                }
                dp = depth(o[x]);
                o[x]._depth = 1 + dp[0];
                o[x]._length = dp[1];
                d = Math.max(d, o[x]._depth);
                l += o[x]._length;
            }
            o._depth = 1 + d;
            o._length = l;
            return [d, l];
        }
        depth(outputConfig);

        var tds = function (o, p, l) {
            for (var x in o) {
                if (!o.hasOwnProperty(x)) {
                    continue;
                }
                if (o[x] === null || o[x] === undefined) {
                    continue;
                }
                if (o[x]._depth) {
                    tr = $("<tr>");
                    td = $("<td>" + x + "</td>").attr('rowspan', o[x]._length + 1);
                    tr.append(td);
                    p.append(tr);
                    tds(o[x], p, l + 1);
                } else {
                    if (x == '_depth') {
                        continue;
                    }
                    if (x == '_length') {
                        continue;
                    }
                    c = true;
                    field = parseField(x, o[x]);
                    tr = $("<tr>");
                    td = $("<td>" + field.name + "</td>").attr("colspan", outputConfig._depth - l);
                    tr.append(td);
                    tr.append(td = $("<td>" + field.label + "</td>"));
                    tr.append(td = $("<td>" + field.comment + "</td>"));
                    p.append(tr);
                }
            }
        }
        tds(outputConfig, tb, 0);


        if (c) {
            th = $("<thead>");
            tr = $("<tr>");
            tr.append($("<th>名称</th>").attr("colspan", outputConfig._depth));
            tr.append($("<th>说明</th>"));
            tr.append($("<th>备注</th>"));
            table.append(th.append(tr));
            table.append(tb);
        }

        return div.append(h4, table);
    };

    var saveFormVars = function () {
        var el = $(this);
        var action = el.attr('data-action');
        el.find('input').each(function () {
            var i = $(this);
            if (i.is('[type=checkbox]') || i.is('[type=file]')) {
                return true;
            }
            $.cookie(action + '-' + i.attr('name'), i.val(), {expires: 30});
            if (window.localStorage) {
                window.localStorage.setItem(action + '-' + i.attr('name'), i.val())
            }
        });
    };

    var loadFormVars = function () {
        var el = $(this);
        var action = el.attr('data-action');
        el.find('input').each(function () {
            var i = $(this);
            var val;
            if (i.is('[type=checkbox]') || i.is('[type=file]')) {
                return true;
            }
            if (window.localStorage && !val) {
                val = window.localStorage.getItem(action + '-' + i.attr('name'));
            }
            i.val(val);
        });
    };

    $('#api_token').change(function () {
        window.localStorage.setItem('api_token', $('#api_token').val());
    }).val(window.localStorage.getItem('api_token'));

    var outputEl = '';

    return builder;
})();